]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
animationUtils: Group together various animation helpers
authorEvan Welsh <contact@evanwelsh.com>
Mon, 10 Jul 2023 04:58:21 +0000 (21:58 -0700)
committerEvan Welsh <contact@evanwelsh.com>
Sat, 15 Jul 2023 02:35:56 +0000 (02:35 +0000)
The environment module is used to initialize the environment, yet it
currently also defines the adjustAnimationTime() function.

Ideally it should not export any utility functions, in particular
once converted to ESM.

The function cannot be moved to the existing Utils module, as that
depends on an initialized environment, and can therefore not be
imported from environment.js, so use that opportunity to group
together several animation helpers in a new animationUtils module.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2822>

js/gdm/authPrompt.js
js/js-resources.gresource.xml
js/misc/animationUtils.js [new file with mode: 0644]
js/misc/util.js
js/ui/calendar.js
js/ui/components/keyring.js
js/ui/components/polkitAgent.js
js/ui/environment.js
js/ui/screenShield.js
js/ui/search.js
js/ui/shellMountOperation.js

index 78bf29dd971ef54961dcd2eb15232d6376934aa1..b10c2678827d40b5fa683ae5348cf007f5c8fbde 100644 (file)
@@ -15,7 +15,7 @@ const GdmUtil = imports.gdm.util;
 const Params = imports.misc.params;
 const ShellEntry = imports.ui.shellEntry;
 const UserWidget = imports.ui.userWidget;
-const Util = imports.misc.util;
+const {wiggle} = imports.misc.animationUtils;
 
 var DEFAULT_BUTTON_WELL_ICON_SIZE = 16;
 var DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1000;
@@ -391,7 +391,7 @@ var AuthPrompt = GObject.registerClass({
             this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED;
 
         if (wasQueryingService)
-            Util.wiggle(this._entry);
+            wiggle(this._entry);
     }
 
     _onVerificationComplete() {
@@ -566,7 +566,7 @@ var AuthPrompt = GObject.registerClass({
             this._message.opacity = 0;
         }
 
-        Util.wiggle(this._message, wiggleParameters);
+        wiggle(this._message, wiggleParameters);
     }
 
     updateSensitivity(sensitive) {
index b1f537cc871191dc04ac405d01dee8af6bbf3113..6aa88ce216db532658e277c5a6ae737ccf1bf6ad 100644 (file)
@@ -11,6 +11,7 @@
     <file>gdm/realmd.js</file>
     <file>gdm/util.js</file>
 
+    <file>misc/animationUtils.js</file>
     <file>misc/config.js</file>
     <file>misc/extensionUtils.js</file>
     <file>misc/fileUtils.js</file>
diff --git a/js/misc/animationUtils.js b/js/misc/animationUtils.js
new file mode 100644 (file)
index 0000000..619d719
--- /dev/null
@@ -0,0 +1,117 @@
+/* exported adjustAnimationTime, ensureActorVisibleInScrollView, wiggle */
+
+const St = imports.gi.St;
+const Clutter = imports.gi.Clutter;
+
+const Params = imports.misc.params;
+
+var SCROLL_TIME = 100;
+
+const WIGGLE_OFFSET = 6;
+const WIGGLE_DURATION = 65;
+const N_WIGGLES = 3;
+
+/**
+ * adjustAnimationTime:
+ *
+ * @param {number} msecs - time in milliseconds
+ *
+ * Adjust `msecs` to account for St's enable-animations
+ * and slow-down-factor settings
+ */
+function adjustAnimationTime(msecs) {
+    const settings = St.Settings.get();
+
+    if (!settings.enable_animations)
+        return 0;
+    return settings.slow_down_factor * msecs;
+}
+
+/**
+ * Animate scrolling a scrollview until an actor is visible.
+ *
+ * @param {St.ScrollView} scrollView - the scroll view the actor is in
+ * @param {Clutter.Actor} actor - the actor
+ */
+function ensureActorVisibleInScrollView(scrollView, actor) {
+    const {adjustment} = scrollView.vscroll;
+    let [value, lower_, upper, stepIncrement_, pageIncrement_, pageSize] = adjustment.get_values();
+
+    let offset = 0;
+    const vfade = scrollView.get_effect('fade');
+    if (vfade)
+        offset = vfade.fade_margins.top;
+
+    let box = actor.get_allocation_box();
+    let y1 = box.y1, y2 = box.y2;
+
+    let parent = actor.get_parent();
+    while (parent !== scrollView) {
+        if (!parent)
+            throw new Error('actor not in scroll view');
+
+        box = parent.get_allocation_box();
+        y1 += box.y1;
+        y2 += box.y1;
+        parent = parent.get_parent();
+    }
+
+    if (y1 < value + offset)
+        value = Math.max(0, y1 - offset);
+    else if (y2 > value + pageSize - offset)
+        value = Math.min(upper, y2 + offset - pageSize);
+    else
+        return;
+
+    adjustment.ease(value, {
+        mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+        duration: SCROLL_TIME,
+    });
+}
+
+/**
+ * "Wiggles" a clutter actor. A "wiggle" is an animation the moves an actor
+ * back and forth on the X axis a specified amount of times.
+ *
+ * @param {Clutter.Actor} actor - an actor to animate
+ * @param {object} params - options for the animation
+ * @param {number} params.offset - the offset to move the actor by per-wiggle
+ * @param {number} params.duration - the amount of time to move the actor per-wiggle
+ * @param {number} params.wiggleCount - the number of times to wiggle the actor
+ */
+function wiggle(actor, params) {
+    if (!St.Settings.get().enable_animations)
+        return;
+
+    params = Params.parse(params, {
+        offset: WIGGLE_OFFSET,
+        duration: WIGGLE_DURATION,
+        wiggleCount: N_WIGGLES,
+    });
+    actor.translation_x = 0;
+
+    // Accelerate before wiggling
+    actor.ease({
+        translation_x: -params.offset,
+        duration: params.duration,
+        mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+        onComplete: () => {
+            // Wiggle
+            actor.ease({
+                translation_x: params.offset,
+                duration: params.duration,
+                mode: Clutter.AnimationMode.LINEAR,
+                repeatCount: params.wiggleCount,
+                autoReverse: true,
+                onComplete: () => {
+                    // Decelerate and return to the original position
+                    actor.ease({
+                        translation_x: 0,
+                        duration: params.duration,
+                        mode: Clutter.AnimationMode.EASE_IN_QUAD,
+                    });
+                },
+            });
+        },
+    });
+}
index e4097acc1cd9452019a73d77a4ef2388eade81a2..8dc6b9905c1badb58c7108bc789203e1cc9c7af4 100644 (file)
@@ -1,9 +1,8 @@
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 /* exported findUrls, spawn, spawnCommandLine, spawnApp, trySpawnCommandLine,
-            createTimeLabel, insertSorted, ensureActorVisibleInScrollView,
-            wiggle, lerp, GNOMEversionCompare, DBusSenderChecker, Highlighter */
+            createTimeLabel, insertSorted, lerp, GNOMEversionCompare,
+            DBusSenderChecker, Highlighter */
 
-const Clutter = imports.gi.Clutter;
 const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
 const Shell = imports.gi.Shell;
@@ -11,15 +10,8 @@ const St = imports.gi.St;
 const GnomeDesktop = imports.gi.GnomeDesktop;
 
 const Main = imports.ui.main;
-const Params = imports.misc.params;
 const {formatTime} = imports.misc.dateUtils;
 
-var SCROLL_TIME = 100;
-
-const WIGGLE_OFFSET = 6;
-const WIGGLE_DURATION = 65;
-const N_WIGGLES = 3;
-
 // http://daringfireball.net/2010/07/improved_regex_for_matching_urls
 const _balancedParens = '\\([^\\s()<>]+\\)';
 const _leadingJunk = '[\\s`(\\[{\'\\"<\u00AB\u201C\u2018]';
@@ -241,79 +233,6 @@ function insertSorted(array, val, cmp) {
     return pos;
 }
 
-function ensureActorVisibleInScrollView(scrollView, actor) {
-    let adjustment = scrollView.vscroll.adjustment;
-    let [value, lower_, upper, stepIncrement_, pageIncrement_, pageSize] = adjustment.get_values();
-
-    let offset = 0;
-    let vfade = scrollView.get_effect("fade");
-    if (vfade)
-        offset = vfade.fade_margins.top;
-
-    let box = actor.get_allocation_box();
-    let y1 = box.y1, y2 = box.y2;
-
-    let parent = actor.get_parent();
-    while (parent != scrollView) {
-        if (!parent)
-            throw new Error("actor not in scroll view");
-
-        box = parent.get_allocation_box();
-        y1 += box.y1;
-        y2 += box.y1;
-        parent = parent.get_parent();
-    }
-
-    if (y1 < value + offset)
-        value = Math.max(0, y1 - offset);
-    else if (y2 > value + pageSize - offset)
-        value = Math.min(upper, y2 + offset - pageSize);
-    else
-        return;
-
-    adjustment.ease(value, {
-        mode: Clutter.AnimationMode.EASE_OUT_QUAD,
-        duration: SCROLL_TIME,
-    });
-}
-
-function wiggle(actor, params) {
-    if (!St.Settings.get().enable_animations)
-        return;
-
-    params = Params.parse(params, {
-        offset: WIGGLE_OFFSET,
-        duration: WIGGLE_DURATION,
-        wiggleCount: N_WIGGLES,
-    });
-    actor.translation_x = 0;
-
-    // Accelerate before wiggling
-    actor.ease({
-        translation_x: -params.offset,
-        duration: params.duration,
-        mode: Clutter.AnimationMode.EASE_OUT_QUAD,
-        onComplete: () => {
-            // Wiggle
-            actor.ease({
-                translation_x: params.offset,
-                duration: params.duration,
-                mode: Clutter.AnimationMode.LINEAR,
-                repeatCount: params.wiggleCount,
-                autoReverse: true,
-                onComplete: () => {
-                    // Decelerate and return to the original position
-                    actor.ease({
-                        translation_x: 0,
-                        duration: params.duration,
-                        mode: Clutter.AnimationMode.EASE_IN_QUAD,
-                    });
-                },
-            });
-        },
-    });
-}
-
 function lerp(start, end, progress) {
     return start + progress * (end - start);
 }
index aa597fc42768c942dfecf483fde5867e6c06c1cd..d87d5aff866f258140a50745da67fdb080be78ff 100644 (file)
@@ -13,7 +13,7 @@ const MessageList = imports.ui.messageList;
 const MessageTray = imports.ui.messageTray;
 const Mpris = imports.ui.mpris;
 const PopupMenu = imports.ui.popupMenu;
-const Util = imports.misc.util;
+const {ensureActorVisibleInScrollView} = imports.misc.animationUtils;
 
 const {formatDateWithCFormatString, formatTimeSpan} = imports.misc.dateUtils;
 const {loadInterfaceXML} = imports.misc.fileUtils;
@@ -1016,7 +1016,7 @@ class CalendarMessageList extends St.Widget {
             'notify::can-clear', this._sync.bind(this),
             'destroy', () => this._sectionList.remove_actor(section),
             'message-focused', (_s, messageActor) => {
-                Util.ensureActorVisibleInScrollView(this._scrollView, messageActor);
+                ensureActorVisibleInScrollView(this._scrollView, messageActor);
             }, this);
         this._sectionList.add_actor(section);
     }
index e4d0ad85f3820f96c7daaafdaaf1d236b3538ae9..fa96553bb0d748c3ab2c54f33772a7a852b9cf96 100644 (file)
@@ -13,7 +13,7 @@ const Dialog = imports.ui.dialog;
 const ModalDialog = imports.ui.modalDialog;
 const ShellEntry = imports.ui.shellEntry;
 const CheckBox = imports.ui.checkBox;
-const Util = imports.misc.util;
+const {wiggle} = imports.misc.animationUtils;
 
 var KeyringDialog = GObject.registerClass(
 class KeyringDialog extends ModalDialog.ModalDialog {
@@ -83,7 +83,7 @@ class KeyringDialog extends ModalDialog.ModalDialog {
         });
         this.prompt.connect('notify::warning', () => {
             if (this._passwordEntry && this.prompt.warning !== '')
-                Util.wiggle(this._passwordEntry);
+                wiggle(this._passwordEntry);
         });
         warningBox.add_child(warning);
 
index 65c4dff71ac06b7c6d59657d2d0d1bc3c089619f..de2f86270fb3cbf76e70bdb47d06ce53dd64f55e 100644 (file)
@@ -16,7 +16,7 @@ const Main = imports.ui.main;
 const ModalDialog = imports.ui.modalDialog;
 const ShellEntry = imports.ui.shellEntry;
 const UserWidget = imports.ui.userWidget;
-const Util = imports.misc.util;
+const {wiggle} = imports.misc.animationUtils;
 
 const DialogMode = {
     AUTH: 0,
@@ -267,7 +267,7 @@ var AuthenticationDialog = GObject.registerClass({
                 this._infoMessageLabel.hide();
                 this._nullMessageLabel.hide();
 
-                Util.wiggle(this._passwordEntry);
+                wiggle(this._passwordEntry);
             }
 
             /* Try and authenticate again */
index 8f75871c31195a116c1e78078ad0bd27ab80d32c..aee0f8ae522a68fbd4e58a9c2620f32d7c82d76d 100644 (file)
@@ -44,6 +44,7 @@ const Shell = imports.gi.Shell;
 const St = imports.gi.St;
 const Gettext = imports.gettext;
 const SignalTracker = imports.misc.signalTracker;
+const {adjustAnimationTime} = imports.misc.animationUtils;
 
 Gio._promisify(Gio.DataInputStream.prototype, 'fill_async');
 Gio._promisify(Gio.DataInputStream.prototype, 'read_line_async');
@@ -389,17 +390,3 @@ function init() {
     // Prevent extensions from opening a display connection to ourselves
     Gdk.set_allowed_backends('');
 }
-
-// adjustAnimationTime:
-// @msecs: time in milliseconds
-//
-// Adjust @msecs to account for St's enable-animations
-// and slow-down-factor settings
-function adjustAnimationTime(msecs) {
-    let settings = St.Settings.get();
-
-    if (!settings.enable_animations)
-        return 0;
-    return settings.slow_down_factor * msecs;
-}
-
index 8a10d7fe34e29f2c3c5c53d0cf1911c6f3f6ab79..39ae22648251319d548094e037bc72f7ac6672ab 100644 (file)
@@ -22,7 +22,7 @@ const MessageTray = imports.ui.messageTray;
 const ShellDBus = imports.ui.shellDBus;
 const SmartcardManager = imports.misc.smartcardManager;
 
-const { adjustAnimationTime } = imports.ui.environment;
+const {adjustAnimationTime} = imports.misc.animationUtils;
 
 const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
 const LOCK_ENABLED_KEY = 'lock-enabled';
index 348f397999ec498def5a3f2a92d2066115a00abd..9e42c9bcea1242cb8a695f4a3daddc0c21ea1c95 100644 (file)
@@ -14,7 +14,7 @@ const IconGrid = imports.ui.iconGrid;
 const Main = imports.ui.main;
 const ParentalControlsManager = imports.misc.parentalControlsManager;
 const RemoteSearch = imports.ui.remoteSearch;
-const Util = imports.misc.util;
+const {ensureActorVisibleInScrollView} = imports.misc.animationUtils;
 
 const { Highlighter } = imports.misc.util;
 
@@ -746,7 +746,7 @@ var SearchResultsView = GObject.registerClass({
     }
 
     _focusChildChanged(provider) {
-        Util.ensureActorVisibleInScrollView(this._scrollView, provider.focusChild);
+        ensureActorVisibleInScrollView(this._scrollView, provider.focusChild);
     }
 
     _ensureProviderDisplay(provider) {
@@ -877,7 +877,7 @@ var SearchResultsView = GObject.registerClass({
 
         if (selected) {
             result.add_style_pseudo_class('selected');
-            Util.ensureActorVisibleInScrollView(this._scrollView, result);
+            ensureActorVisibleInScrollView(this._scrollView, result);
         } else {
             result.remove_style_pseudo_class('selected');
         }
index 86ec781fceda16f688e96aeedffe8d3231446f05..591d88b1aa314e21ffe1403086ceedd037633d42 100644 (file)
@@ -19,7 +19,7 @@ const Params = imports.misc.params;
 const ShellEntry = imports.ui.shellEntry;
 
 const { loadInterfaceXML } = imports.misc.fileUtils;
-const Util = imports.misc.util;
+const {wiggle} = imports.misc.animationUtils;
 
 var LIST_ITEM_ICON_SIZE = 48;
 var WORK_SPINNER_ICON_SIZE = 16;
@@ -421,7 +421,7 @@ var ShellMountPasswordDialog = GObject.registerClass({
         this._errorMessageLabel.text = _('Sorry, that didn’t work. Please try again.');
         this._errorMessageLabel.opacity = 255;
 
-        Util.wiggle(this._passwordEntry);
+        wiggle(this._passwordEntry);
     }
 
     _onCancelButton() {